home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / dino / dino_bot.1 / source / library / D_reduct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-27  |  18.8 KB  |  556 lines

  1. /* Copyright, 1990, Regents of the University of Colorado */
  2.                    /***************************************
  3.                     ***************************************
  4.                     **                                   **
  5.                     **  IPSC1 Run Time Library for DINO  **
  6.                     **      REDUCTION function           **
  7.                     **                                   **
  8.                     **                                   **
  9.                     ***************************************
  10.                     ***************************************/
  11.  
  12. #include "D_lib.h"
  13. #include "internal.h"
  14. #include "export.h"
  15. #include "route.h"
  16. #include <stdio.h>
  17. #if D_MACH==D_CUBE
  18. #include <dos/malloc.h> 
  19. #else
  20. #include <malloc.h>
  21. #endif 
  22. #include <ctype.h>
  23.  
  24.  
  25.  
  26.  
  27.                    /*****************************
  28.                     *                           *
  29.                     *     Library variables.    *
  30.                     *                           *
  31.                     *****************************/
  32.  
  33. extern int D_ci;                   /* Channel number. */
  34.  
  35. D_BOOL NODIAG = FALSE;
  36.  
  37. static long int loc;
  38. static int parts,size;
  39. static D_BOOL contig;
  40. static long int header[D_RED_HD_SZ];
  41. static long int header_size = sizeof(header);
  42.  
  43.                 /*****************************
  44.                     *                           *
  45.                     *     Calculate size &      *
  46.                     *     contiquity            *
  47.                     *                           *
  48.                     *****************************/
  49.  
  50.  
  51. void D_calc_red_size(P_size,P_contig,P_ddd,P_loc,P_ssd)
  52.     int *P_size;
  53.     long int *P_loc;
  54.     D_BOOL *P_contig;
  55.     D_data_distribution_desc *P_ddd;
  56.     D_storage_space_desc *P_ssd;
  57.     {
  58.     D_BOOL flip;
  59.     int I;
  60.  
  61.     *P_contig = TRUE;
  62.     
  63.     if (P_ddd->needed)
  64.         {
  65.         *P_size = 1;
  66.         flip = FALSE;
  67.         
  68. /*        for (I = 0; I < P_ddd->dims; I++) */
  69.       for (I = P_ddd->dims - 1; I >= 0; I--)
  70.             {
  71.             *P_size *= (P_ddd->range[I].last - P_ddd->range[I].first + 1);
  72.             if (flip)
  73.                 {
  74.                 if (P_ddd->range[I].last != P_ddd->range[I].first)
  75.                     *P_contig = FALSE;
  76.                 }   
  77.             else
  78.                 {
  79.                 if (P_ddd->range[I].first != 0 ||
  80.                     P_ddd->range[I].last != (P_ddd->range[I].size - 1))
  81.                         flip = TRUE;
  82.                 }
  83.             }
  84.         if (*P_contig)
  85.             {   
  86.                 *P_loc = P_ddd->range[0].first;
  87.                 for (I = 1; I < P_ddd->dims; I++)
  88.                     *P_loc = *P_loc * P_ddd->range[I].size + 
  89.                                 P_ddd->range[I].first;
  90.             }
  91.         }
  92.     else /* (the data distribution descriptor is not needed) */
  93.                     /* Calculate size. */
  94.         *P_size = P_ssd->size;
  95.  
  96.     }
  97.                 /*****************************
  98.                     *                           *
  99.                     *     Send Reduction Msg    *
  100.                     *     (all parts if bigger  *
  101.                     *       then max msg size)  *
  102.                     *                           *
  103.                     *****************************/
  104.  
  105.  
  106. void D_reduct_send(bufptr,parts,P_first, node, pid, P_type, sub_type,header,
  107.                     P_ssd,P_ssd_ind,P_ddd,P_td,P_clist,P_size,P_loc)
  108.     char *bufptr;
  109.     int parts;
  110.     D_BOOL P_first; /* set if this is the first msg of same data
  111.                      going to multiple nodes */
  112.     int node,pid,P_type,sub_type,P_size;
  113.     long int P_loc;
  114.     long header[D_RED_HD_SZ];
  115.     D_storage_space_desc *P_ssd, *P_ssd_ind;
  116.     D_data_distribution_desc *P_ddd;
  117.     D_reduct_type_descriptor *P_td;
  118.     D_copy_list *P_clist;
  119.         {
  120.         char *dataptr, *charp, *buf, *indexptr;
  121.         int I,J,K, data_size, index_size,size,type; 
  122.         long int offset;
  123.         dataptr = P_ssd->loc + P_loc;
  124.         buf = bufptr;
  125.         offset  = 0;
  126.         if (P_first)
  127.             {
  128.             
  129.             /* set up header for sends */
  130.             /* PM */
  131.             header[0] = parts;
  132.             header[1] = (parts > 1)?sub_type:0;
  133.             /* MP */
  134.             header[2] = 1;
  135.             header[3] = node;
  136.             header[4] = pid;
  137.             header[5] = D_ENV_INFO_LEN;
  138.             header[6] = 0;
  139.             /* LM */
  140.             header[8] = 1;
  141.             header[9] = D_ENV_INFO_LEN;
  142.             header[10]=0;
  143.             /* LME */
  144.             header[11] = P_td->D_reduct_type;  
  145.             header[12]= 2 * sizeof(long int); /*length of red. header info */
  146.             /* reduction header info */
  147.             header[14]= P_td->D_reduct_data_type;
  148.             header[15]= P_size ; /* size excluding index */
  149.             }
  150.         else
  151.             {
  152.             header[3] = node;
  153.             header[4] = pid;
  154.             }
  155.     if (!contig) ddd_xform(P_ssd,P_ddd,P_clist);
  156.         for (I=1; I<= parts; I++)
  157.             {
  158.                 data_size = (parts > I)?
  159.                         (int)(D_MAX_MESS - header_size): (int)(P_size - offset);
  160.                 /* length of LM *
  161.                 header[7] = header_size + data_size - (D_PM_SZ + D_MP_SZ); 
  162.                 /* length of data , excluding index if applicable */
  163.                 header[13] = (long int)data_size;
  164.  
  165.                 bufptr = buf;
  166.  
  167.             
  168.             /* copy  header to buffer */
  169.                 charp = (char *) header;
  170.                 for (J=0; J<header_size;J++)
  171.                     *(bufptr++) = *(charp++);   
  172.  
  173.             /* copy data to buffer */
  174.  
  175.             if (!contig ) copy_data(P_ssd, P_clist,
  176.                                     (long int) data_size, &bufptr, TRUE);
  177.             else
  178.                 for (K = 0; K < data_size; K++)
  179.                      *(bufptr++) = *(dataptr++);
  180.             offset += data_size;
  181.  
  182.             if ((P_td->D_reduct_type == D_TYPE_GMINDEX) ||
  183.                     (P_td->D_reduct_type == D_TYPE_GMAXDEX))
  184.                     {
  185.                     indexptr = P_ssd_ind->loc;
  186.                     index_size = P_ssd_ind->size;
  187.                     for (K=0; K< index_size; K++)
  188.                          *(bufptr++) = *(indexptr++);
  189.                     }
  190.             else index_size = 0;
  191.             offset += index_size;
  192.                     
  193.             size=header_size + data_size + index_size;
  194.             type = ((I==1)?P_type:sub_type);
  195.             /* send out msg using approprate hypercube call */
  196. #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
  197.             sendmsg(D_ci,type,buf,size,node, pid);
  198. #else
  199. #if (D_MACH==D_SIM || D_MACH==D_CUBE)
  200.             sendw(D_ci,type,buf,size,node, pid);
  201. #else         
  202.             csend((long)type,buf,(long)size,(long)node, (long)pid);
  203. #endif
  204. #endif  
  205.         }       
  206.             
  207.     }
  208.  
  209.                 /*****************************
  210.                     *                           *
  211.                     *     Recv Reduction Msg    *
  212.                     *     (all parts if bigger  *
  213.                     *       then max msg size)  *
  214.                     *                           *
  215.                     *****************************/
  216.  
  217.          
  218. void D_reduct_recv(P_node,P_pid,P_parts,P_ssd,P_ssd_ind,bufptr,P_type,P_td,P_size)
  219. int P_node,P_pid,P_type;
  220. int P_parts,P_size;
  221. D_storage_space_desc *P_ssd,*P_ssd_ind;
  222. char *bufptr;
  223. D_reduct_type_descriptor *P_td;
  224.     {
  225.     int I,J;
  226.     int cnt;
  227.     int size, type,node,pid,K;
  228.     long int header[D_RED_HD_SZ],data_size, index_size;
  229.     char *charp,*headptr,*dataptr, *indexptr, *tmpptr;
  230.     int subtype=0;
  231.     dataptr = P_ssd->loc;
  232.     size=D_MAX_MESS;
  233.     for (I=1; I<= P_parts; I++)
  234.         {
  235.         if (I == 1) type=P_type;
  236.         else type=subtype;
  237.  
  238. #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
  239.  
  240.                 /* check buffer for P_type */
  241.                 /* if not already in buffer, loop */
  242. /*     recvmsg(D_ci, &type, &(D_mess_buf[0]),size, &cnt, &node,&pid);*/
  243.                 /* buffer this msg if P_type != type , else break*/
  244.         tmpptr = bufptr;
  245.         D_recvh(D_ci, type, &tmpptr, D_MAX_MESS,&cnt, &node, &pid);
  246.  
  247.  
  248. #else 
  249. #if (D_MACH==D_SIM || D_MACH==D_CUBE)
  250.                 recvw(D_ci,  type,&(D_mess_buf[0]),D_MAX_MESS, &cnt, &node, &pid);
  251. #else
  252.                 crecv((long)type,&(D_mess_buf[0]),(long)D_MAX_MESS);
  253.                 node=(int)infonode();
  254.                 pid=(int)infopid();
  255.                 cnt=(int)infocount();
  256. #endif
  257. #endif
  258.                         
  259.             /* check if correct msg was received */
  260.             if ((node != P_node) || (pid != P_pid))
  261.                 {
  262. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
  263.                 syslog (mypid(),
  264.                     "received incorrect msg for this node in reduction call");
  265. #else
  266.                 fprintf(stderr,"ENV:%d,INDEX:%d;received incorrect msg for this node in reduction call\n",D_my_env.name,D_my_env.index);
  267. #endif
  268.                 exit(1);
  269.                 }
  270.     
  271.             /* copy to header */
  272.             
  273.             charp = bufptr;
  274.             headptr = (char *) header;
  275.             
  276.             for (J=0;J<header_size;J++)
  277.                 *(headptr++) = *(charp++);
  278.                 
  279.             subtype=(P_parts > 1) ? header[1]:0;
  280.  
  281.             /* check type/size info of msg, if not consistent,
  282.                 send msg to syslog & stop computation */
  283.             if(P_size != header[15])
  284.                 {
  285. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
  286.                 syslog (mypid(),
  287.                     "received inconsistent data size in reduction call");
  288. #else
  289.                 fprintf(stderr,"ENV:%d,INDEX:%d;received inconsistent data size in reduction call\n",D_my_env.name,D_my_env.index);
  290. #endif
  291.                 exit(1);
  292.                 }
  293.  
  294.             if (P_td->D_reduct_type != header[11])
  295.                 {
  296. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
  297.                 syslog (mypid(),
  298.                     "received wrong red. function msg in reduction call");
  299. #else
  300.                 fprintf(stderr,"ENV:%d,INDEX:%d;received wrong red. function msg in reduction call\n",D_my_env.name,D_my_env.index);
  301. #endif
  302.                 exit(1);
  303.                 }
  304.  
  305.             if (P_td->D_reduct_data_type != header[14])
  306.                 {
  307. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL ) 
  308.                 syslog (mypid(),
  309.                     "received inconsistent data element type in reduction call");
  310. #else
  311.                 fprintf(stderr,"ENV:%d,INDEX:%d;received inconsistent data element type in reduction call\n",D_my_env.name,D_my_env.index);
  312. #endif
  313.                 exit(1);
  314.                 }
  315.             
  316.                 /* copy data to data buffer */
  317.                 data_size = (int)header[13];
  318.                                         
  319.                 for (K = 0; K < data_size; K++)
  320.                         *(dataptr++) = *(charp++);
  321.                 if ((P_td->D_reduct_type == D_TYPE_GMINDEX) ||
  322.                     (P_td->D_reduct_type == D_TYPE_GMAXDEX))
  323.                     {
  324.                     indexptr = P_ssd_ind->loc;
  325.                     index_size = P_ssd_ind->size;
  326.                     for (K=0; K< index_size; K++)
  327.                          *(indexptr++) = *(charp++);
  328.                     }               
  329.         }
  330.     }
  331.  
  332.     
  333.                 /*****************************
  334.                     *                           *
  335.                     *     Free buffers malloced * 
  336.                     *     by library.           *
  337.                     *                           *
  338.                     *****************************/
  339.  
  340.  /* called by compiler to free buffers..  */
  341. void D_reduct_free(P_alloc,P_ssd_lib,P_ssd_lhs) 
  342. int P_alloc;
  343. D_storage_space_desc *P_ssd_lib,*P_ssd_lhs;
  344.     {
  345.     if (P_alloc == 2)
  346.         {
  347.         free((char *)P_ssd_lib->loc);
  348.         free((char *)P_ssd_lhs->loc);
  349.         }
  350.     if (P_alloc == 1) free((char *)P_ssd_lib->loc);
  351.         
  352.     }
  353.  
  354.             /*****************************
  355.                     *                           *
  356.                     *     reductn function      *
  357.                     *     called by compiler    *
  358.                     *     for all reductions    *
  359.                     *                           *
  360.                     *****************************/  
  361.  
  362. void D_reductn(P_ssd_lhs,P_ssd_lib,P_ssd_lib_ind,P_ssd_in,P_ssd_in_ind,
  363.                 P_ddd_in,P_td,P_es,P_done,P_first,P_alloc,P_step,P_clist)
  364.  
  365.     D_storage_space_desc *P_ssd_lhs,*P_ssd_lib,*P_ssd_lib_ind,*P_ssd_in,
  366.                             *P_ssd_in_ind;
  367.     D_data_distribution_desc *P_ddd_in;
  368.     D_reduct_type_descriptor *P_td;
  369.     D_env_set *P_es;
  370.     D_BOOL *P_done,P_first;
  371.     int P_alloc,P_step;
  372.     D_copy_list  *P_clist; /* this will change after bob changes the clist
  373.                                 data structure */
  374.     {
  375.     int node,pid,I,type,e_count;
  376.     envvar *route;
  377.     D_route_type route_type;
  378.     char *tree,*bufptr;
  379.     D_BOOL first;
  380.         if (P_first) 
  381.         {
  382.                     /* Calculate size and contiguity. */
  383.  
  384.                 if (P_td->D_reduct_type != D_TYPE_GMAXDEX && 
  385.                     P_td->D_reduct_type != D_TYPE_GMINDEX)
  386.                         {
  387.                         D_calc_red_size(&size,&contig,P_ddd_in,&loc,P_ssd_in);
  388.                     }
  389.                 else
  390.                 {
  391.                     size = P_ssd_in->size;
  392.                     contig = TRUE;
  393.                 }
  394.             
  395.             /* do necessary mallocs  (based on P_alloc) */
  396.  
  397.             /* first check if size is too big to do mallocs on IPSC1 -- */
  398.                 
  399.             if (P_alloc < 3  && size > D_MAX_MALLOC_SZ) 
  400.                 {
  401. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
  402.                 syslog(mypid(),"Required buffer size too large in reduction call.\n");
  403. #else
  404.                 fprintf(stderr,"ENV:%d,INDEX:%d;Required buffer size too large in reduction call.\n",D_my_env.name,D_my_env.index);
  405. #endif
  406.                 exit(1);
  407.                 }
  408.  
  409.             if (P_alloc == 2)
  410.             {
  411.                 /* malloc lib buffer */
  412.                 if ((P_ssd_lib->loc = malloc((unsigned) size)) == NULL)
  413.                     {
  414. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
  415.                     syslog(mypid(), "Error allocating reduction buffer memory.\n");
  416. #else
  417.                     fprintf(stderr,"ENV:%d,INDEX:%d;Error allocating reduction buffer memory.\n",D_my_env.name,D_my_env.index);
  418. #endif
  419.                     exit(1);
  420.                     }
  421.             
  422.                 /* malloc lhs buffer */
  423.                 if ((P_ssd_lhs->loc = malloc((unsigned) size)) == NULL)
  424.                     {
  425. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL) 
  426.                     syslog(mypid(), "Error allocating reduction buffer memory.\n");
  427. #else
  428.                     fprintf(stderr,"ENV:%d,INDEX:%d;Error allocating reduction buffer memory.\n",D_my_env.name,D_my_env.index);
  429. #endif
  430.                     exit(1);
  431.                     }
  432.             }
  433.             else
  434.             {
  435.                 if (P_alloc == 1)
  436.                     /* malloc lib buffer */
  437.                     if ((P_ssd_lib->loc = malloc((unsigned) size)) == NULL)
  438.                         { 
  439. #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL) 
  440.                            syslog(mypid(), "Error allocating reduction buffer memory.\n");
  441. #else
  442.                             fprintf(stderr,"ENV:%d,INDEX:%d;Error allocating reduction buffer memory.\n",D_my_env.name,D_my_env.index);
  443. #endif
  444.  
  445.                         exit(1);
  446.                         }
  447.             }
  448.             
  449.             if (size +  header_size > D_MAX_MESS)
  450.                 parts = (size + header_size) / D_MAX_MESS + (((size +
  451.                                         header_size) % D_MAX_MESS)?1:0);
  452.                 
  453.             else
  454.                 parts=1; 
  455.  
  456.             /* modify env. set for routing subroutines */
  457.  
  458.             if (P_es->count > 1)
  459.                 {
  460.                 e_count = P_es->count;
  461.                 for (I=1; I<e_count;I++)
  462.                     if (P_es[I].count == 0) P_es->count--;
  463.                 }
  464.  
  465.    
  466.                         
  467.             /* call D_route_cube_init */
  468.  
  469.             D_route_cube_init(P_es);
  470.  
  471.  
  472.             if (parts > 1)
  473.                 D_sub_type = get_type();
  474.         
  475.         } /* end of processing for first red. call */
  476.  
  477.         if (P_step == 1 && (P_td->D_reduct_type != D_TYPE_GMAXDEX && 
  478.                     P_td->D_reduct_type != D_TYPE_GMINDEX))
  479.         {
  480.                 D_calc_red_size(&size,&contig,P_ddd_in,&loc,P_ssd_in);
  481.         }
  482.  
  483.  
  484.         route = D_route_cube(P_es,P_done,&tree,&route_type,&P_step);
  485.         node = D_env_lookup[route->name][route->index].node;
  486.         pid = D_env_lookup[route->name][route->index].pid;
  487.  
  488.         /* compute msg type for this step */
  489.         type = D_START_RED_MSG_TYPE + P_step;
  490.  
  491.  
  492.         /* route_type == D_route_pair ==> route contains where to
  493.             send & recv from, 
  494.                    route_type == D_route_rcvsnd ==> send to the nodes in
  495.              the bitmap pointed to by tree(in env. route->name, 
  496.              & if tree is null, send to all nodes in route->name.
  497.             recv from the envvar that route points to.
  498.            route_type == D_route_recv ==> recv from the envvar that route
  499.             points to.
  500.         */
  501.         
  502.         bufptr = (char *) &(D_mess_buf[0]);
  503.         
  504.         switch (route_type)
  505.         {
  506.             case D_route_recv: 
  507.                 D_reduct_recv(node,pid,parts,P_ssd_lib,P_ssd_lib_ind,
  508.                         bufptr,type,P_td,size);
  509.                 break;
  510.             case D_route_pair: 
  511.                 D_reduct_send(bufptr,parts,TRUE,node,pid,
  512.                         type,D_sub_type,header,P_ssd_in,
  513.                         P_ssd_in_ind,P_ddd_in,P_td,P_clist,size,loc);
  514.                 D_reduct_recv(node,pid,parts,
  515.                         P_ssd_lib,P_ssd_lib_ind,bufptr,type,P_td,size);
  516.                 break;
  517.             case D_route_rcvsnd: 
  518.                 first=TRUE;
  519.                 if (tree == NULL)
  520.                 {
  521.                     /*send to all nodes in envset */
  522.                     for (I=0; I< D_env_table[route->name].size; I++)
  523.                     {
  524.                         D_reduct_send(bufptr,parts,first,
  525.                             D_env_lookup[route->name][I].node,
  526.                             D_env_lookup[route->name][I].pid,
  527.                             type,D_sub_type,header,P_ssd_in,
  528.                             P_ssd_in_ind,P_ddd_in,P_td,P_clist,
  529.                             size,loc);
  530.                         first = FALSE;
  531.                     }
  532.                 }
  533.                 else
  534.                 {
  535.                     /*send to nodes set in tree */
  536.                     for (I=0; I< D_env_table[route->name].size; I++)
  537.                     {
  538.                         if (tree[I]==1)
  539.                         {
  540.                             D_reduct_send(bufptr,parts,first,
  541.                                 D_env_lookup[route->name][I].node,
  542.                                 D_env_lookup[route->name][I].pid,
  543.                                 type,D_sub_type,header,P_ssd_in,
  544.                                 P_ssd_in_ind,P_ddd_in,
  545.                                 P_td,P_clist,size,loc);
  546.                             first = FALSE;
  547.                         }
  548.                     }
  549.  
  550.                 }
  551.                 D_reduct_recv(node,pid,parts,
  552.                     P_ssd_lib,P_ssd_lib_ind,bufptr,type,P_td,size);
  553.         
  554.         }
  555.     }
  556.